<template>
  <div class="category-scroller">
    <!-- 左箭头 -->
    <button
      class="scroll-button left"
      @click.stop.prevent="scroll(-1)"
      :disabled="!hasLeftScroll"
      aria-label="Scroll left">
      <svg
        width="24"
        height="24"
        viewBox="0 0 24 24"
        fill="none"
        xmlns="http://www.w3.org/2000/svg">
        <g clip-path="url(#clip0_2886_12047)">
          <circle cx="12" cy="12" r="12" fill="black" fill-opacity="0.32" />
          <path
            d="M13.84 7.41068C14.0073 7.24331 14.2786 7.24331 14.446 7.41068C14.6133 7.57805 14.6133 7.84934 14.446 8.01671L10.4633 11.9994L14.446 15.9821C14.6133 16.1495 14.6133 16.4208 14.446 16.5881C14.2786 16.7555 14.0073 16.7555 13.84 16.5881L9.55424 12.3024C9.38687 12.1351 9.38687 11.8638 9.55424 11.6964L13.84 7.41068Z"
            fill="white" />
        </g>
        <defs>
          <clipPath id="clip0_2886_12047">
            <rect width="24" height="24" fill="white" />
          </clipPath>
        </defs>
      </svg>
    </button>

    <!-- 可滚动的分类容器 -->
    <div ref="scrollContainer" class="scroll-container" @scroll="handleScroll" @wheel="handleWheel">
      <div class="items-container" ref="itemsContainer">
        <div
          v-for="item in items"
          :key="item.id"
          class="item"
          :class="{ active: item.id === activeId }"
          @click.stop="selectItem(item.id)">
          <!-- 第一行：图片 -->
          <div class="image-container">
            <img
              :src="item.image || 'https://placehold.co/60x60'"
              :alt="item.name"
              class="item-image" />
          </div>
          <!-- 第二行：name -->
          <div class="name">
            {{ item.name }}
          </div>
        </div>
      </div>
    </div>

    <!-- 右箭头 -->
    <button
      class="scroll-button right"
      @click.stop.prevent="scroll(1)"
      :disabled="!hasRightScroll"
      aria-label="Scroll right">
      <svg
        width="24"
        height="24"
        viewBox="0 0 24 24"
        fill="none"
        xmlns="http://www.w3.org/2000/svg">
        <g clip-path="url(#clip0_2886_12043)">
          <circle cx="12" cy="12" r="12" fill="black" fill-opacity="0.32" />
          <path
            d="M9.55424 7.41068C9.7216 7.24331 9.9929 7.24331 10.1603 7.41068L14.446 11.6964C14.6133 11.8638 14.6133 12.1351 14.446 12.3024L10.1603 16.5881C9.9929 16.7555 9.7216 16.7555 9.55424 16.5881C9.38687 16.4208 9.38687 16.1495 9.55424 15.9821L13.5369 11.9994L9.55424 8.01671C9.38687 7.84934 9.38687 7.57805 9.55424 7.41068Z"
            fill="white" />
        </g>
        <defs>
          <clipPath id="clip0_2886_12043">
            <rect width="24" height="24" fill="white" />
          </clipPath>
        </defs>
      </svg>
    </button>
  </div>
</template>

<script setup lang="ts">
  import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';

  // 组件Props
  interface Item {
    id: number;
    name: string;
    image?: string;
  }

  interface Props {
    items: Item[];
    activeId: number;
    itemWidth?: number;
    itemGap?: number;
    height?: number;
  }

  const props = withDefaults(defineProps<Props>(), {
    itemWidth: 120,
    itemGap: 16,
    height: 120,
  });

  // 组件Events
  const emit = defineEmits<{
    'update:activeId': [id: number];
  }>();

  // 响应式引用
  const scrollContainer = ref<HTMLElement>();
  const itemsContainer = ref<HTMLElement>();
  const hasLeftScroll = ref(false);
  const hasRightScroll = ref(true);
  const itemSize = ref(props.itemWidth + props.itemGap); // 包含间距的item总宽度

  // 滚动处理函数
  const scroll = (direction: number) => {
    if (!scrollContainer.value) return;

    const scrollAmount = itemSize.value; // 每次滚动一个item的宽度（包含间距）
    scrollContainer.value.scrollBy({
      left: direction * scrollAmount,
      behavior: 'smooth',
    });
  };

  // 滚动事件处理
  const handleScroll = () => {
    if (!scrollContainer.value) return;
    const { scrollLeft, scrollWidth, clientWidth } = scrollContainer.value;
    hasLeftScroll.value = scrollLeft > 5;
    hasRightScroll.value = scrollLeft < scrollWidth - clientWidth - 5;
  };

  // 鼠标滚轮处理
  const handleWheel = (event: WheelEvent) => {
    if (!scrollContainer.value) return;
    event.preventDefault();
    scrollContainer.value.scrollBy({
      left: event.deltaY > 0 ? itemSize.value : -itemSize.value,
      behavior: 'smooth',
    });
  };

  // 选择项
  const selectItem = (id: number) => {
    emit('update:activeId', id);
  };

  // 监听props变化
  watch(
    () => [props.itemWidth, props.itemGap],
    ([newWidth, newGap]) => {
      itemSize.value = newWidth + newGap;
    }
  );

  watch(
    () => props.items,
    (newItems) => {
      nextTick(() => {
        handleScroll();
      });
    }
  );

  // 监听激活项变化，滚动到可视区域
  watch(
    () => props.activeId,
    async (newActiveId) => {
      await nextTick();
      if (!scrollContainer.value || !itemsContainer.value) return;

      const activeElement: HTMLElement | null = itemsContainer.value.querySelector(`.item.active`);
      if (activeElement) {
        const containerRect = scrollContainer.value.getBoundingClientRect();
        const elementRect = activeElement.getBoundingClientRect();

        // 如果元素不在可视区域内，则滚动到可视区域
        if (elementRect.left < containerRect.left || elementRect.right > containerRect.right) {
          scrollContainer.value.scrollTo({
            left: activeElement.offsetLeft - containerRect.width / 2 + elementRect.width / 2,
            behavior: 'smooth',
          });
        }
      }
    }
  );

  // 组件挂载后初始化
  onMounted(() => {
    nextTick(() => {
      handleScroll();
    });
  });
</script>

<style lang="scss" scoped>
  @use '@/styles/variables' as *;

  .category-scroller {
    display: flex;
    align-items: center;
    position: relative;
    min-height: v-bind('props.height + "px"');
  }

  .scroll-button {
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 10;
    outline: none;
    transition: all 0.3s ease;
    flex-shrink: 0;
    position: absolute;
    top: calc(50% - 26px);
    transform: translateY(-50%);

    &.left {
      left: 5px;
    }

    &.right {
      right: 5px;
    }

    &:disabled {
      display: none;
    }
  }

  .scroll-container {
    flex: 1;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none; /* IE 10+ */
    height: 100%;

    &::-webkit-scrollbar {
      display: none; /* Chrome, Safari, Edge */
    }
  }

  .items-container {
    display: flex;
    gap: v-bind('props.itemGap + "px"');
    height: 100%;
  }

  .item {
    width: v-bind('props.itemWidth + "px"');
    cursor: pointer;
    border-radius: 8px;
    text-align: center;
    transition: all 0.3s ease;
    height: 100%;
    box-sizing: border-box;
    &.active {
      .name {
        color: #f76b1b;
      }
      .image-container {
        border-color: #f76b1b;
        &:hover {
          border-color: #f76b1b;
        }
      }
    }

    .image-container {
      width: 120px;
      height: 120px;
      overflow: hidden;
      border-radius: 8px;
      background-color: #f8f8f8;
      flex-shrink: 0;
      border: 2px solid #ededed;
      margin-bottom: 8px;
      transition: all 0.3s ease;
      &:hover {
        border-color: #cbcbcb;
      }
    }

    .item-image {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    .name {
      font-size: 14px;
      font-weight: 500;
      color: #222222;
    }
  }
</style>
